package main

import (
	"context"
	"time"

	"github.com/go-redis/redis/v8"
)

// rdb redis 连接
var rdb *redis.Client

// initRedis 初始化redis 连接
func initRedis(addr string, password string) {
	rdb = redis.NewClient(&redis.Options{
		Addr:         addr,
		Password:     password, // no password set
		DB:           0,        // use default DB
		DialTimeout:  100 * time.Second,
		ReadTimeout:  300 * time.Second,
		WriteTimeout: 300 * time.Second,
		PoolSize:     10,
		PoolTimeout:  300 * time.Second,
	})
}

// get redis get
func Get(key string) (string, error) {
	return rdb.Get(context.Background(), key).Result()
}

// set redis set
func Set(key string, value string, t time.Duration) error {
	return rdb.Set(context.Background(), key, value, t).Err()
}

// setNX redis setNX
func SetNX(key string, value string, t time.Duration) (bool, error) {
	return rdb.SetNX(context.Background(), key, value, t).Result()
}

// del redis del
func Del(key string) (int64, error) {
	return rdb.Del(context.Background(), key).Result()
}

// ZAdd 添加集合数据
func ZAdd(key, name string, val float64) error {
	zD := &redis.Z{val, name}
	return rdb.ZAdd(context.Background(), key, zD).Err()
}

// ZRem 删除数据
func ZRem(key, name string) error {
	return rdb.ZRem(context.Background(), key, name).Err()
}

// ZRange 获取所有数据
func ZRange(key string) ([]string, error) {
	return rdb.ZRange(context.Background(), key, 0, -1).Result()
}

// Keys 添加集合数据
func Keys(key string) ([]string, error) {
	return rdb.Keys(context.Background(), key).Result()
}

type Locker struct {
	locker *Client
	tag    string
	ctx    context.Context
	lock   *Lock
}

// NewLocker 创建锁
func NewLocker(ctx context.Context, client RedisClient, tag string) *Locker {
	return &Locker{ctx: ctx, locker: New(client), tag: tag}
}

// Lock 加锁
func (l *Locker) Lock(ttl time.Duration) bool {
	lock, err := l.locker.Obtain(l.ctx, l.tag, ttl, nil)
	if err != nil {
		return false
	}
	l.lock = lock
	return true
}

// Unlock 释放锁
func (l *Locker) Unlock() error {
	return l.lock.Release(l.ctx)
}
